/**
 *
 * <p>
 * Licensed under the Apache License, Version 2.0 (the "License"); you may not
 * use this file except in compliance with the License. You may obtain a copy of
 * the License at
 * <p>
 * http://www.apache.org/licenses/LICENSE-2.0
 * <p>
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
 * License for the specific language governing permissions and limitations under
 * the License.
 */

package com.cqndt.disaster.device.common.shrio;


import com.cqndt.disaster.device.common.util.Constant;
import com.cqndt.disaster.device.dao.SysMenuMapper;
import com.cqndt.disaster.device.dao.TabUserMapper;
import com.cqndt.disaster.device.vo.TabUserVo;
import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authc.credential.CredentialsMatcher;
import org.apache.shiro.authc.credential.HashedCredentialsMatcher;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.SessionDAO;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.apache.shiro.web.mgt.DefaultWebSecurityManager;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;


/**
 * 权限、登录认证
 */
@Component
public class UserRealm extends AuthorizingRealm {
    @Autowired
    private TabUserMapper tabUserMapper;
	@Autowired
	private SysMenuMapper sysMenuMapper;

	/**
	 * 用户权限
	 * @param principals
	 * @return
	 */
	@Override
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
		TabUserVo user = (TabUserVo)principals.getPrimaryPrincipal();
		Long userId = user.getId().longValue();
		//超级管理员所有权限
		List<String> permsList;
		if(userId.toString().equals(Constant.SUPER_ADMIN.toString())){
			permsList = sysMenuMapper.queryPermsForAdmin();
		}else{
			permsList = sysMenuMapper.queryPermsForUser(userId.toString());
		}
		//用户权限列表
		Set<String> permsSet = new HashSet<>();
		for(String perms : permsList){
			if(StringUtils.isBlank(perms)){
				continue;
			}
			permsSet.addAll(Arrays.asList(perms.trim().split(",")));
		}
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		info.setStringPermissions(permsSet);
		return info;
	}

	/**
	 * 认证(登录时调用)
	 */
	@Override
	protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authcToken) throws AuthenticationException {
		UsernamePasswordToken token = (UsernamePasswordToken)authcToken;
		//查询用户信息
		TabUserVo user = new TabUserVo();
		System.out.println(user);
		user.setUserName(token.getUsername());
		user = tabUserMapper.getUserByUserName(user);
		//账号不存在
		if(user == null) {
			throw new UnknownAccountException("账号或密码错误");
		}
		//账号锁定
		if("0".equals(user.getStatus())){
			throw new LockedAccountException("账号已被禁用,请联系管理员");
		}

		//用户为省级，同一账号第二个不能登录成功
		if("1".equals(user.getLevel())){
			DefaultWebSecurityManager securityManager = (DefaultWebSecurityManager) SecurityUtils.getSecurityManager();
			DefaultWebSessionManager sessionManager = (DefaultWebSessionManager)securityManager.getSessionManager();
			Collection<Session> sessions = sessionManager.getSessionDAO().getActiveSessions();//获取当前已登录的用户session列表
			for(Session session:sessions){
				if(token.getUsername().equals(String.valueOf(session.getAttribute(Constant.USER_NAME)))) {
					throw new AuthenticationException("该用户已登录,不能重复登录");
				}
			}
		}
		SimpleAuthenticationInfo info = new SimpleAuthenticationInfo(user, user.getPassword(), ByteSource.Util.bytes(user.getSalt()), getName());
		return info;
	}

	@Override
	public void setCredentialsMatcher(CredentialsMatcher credentialsMatcher) {
		HashedCredentialsMatcher shaCredentialsMatcher = new HashedCredentialsMatcher();
		shaCredentialsMatcher.setHashAlgorithmName(ShiroUtils.hashAlgorithmName);
		shaCredentialsMatcher.setHashIterations(ShiroUtils.hashIterations);
		super.setCredentialsMatcher(shaCredentialsMatcher);
	}
}
